home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK2.toast / Development Kits (Disc 2) / ScriptX / Draggable ScriptX Folders / utils / c-api / bitarray.c next >
Encoding:
C/C++ Source or Header  |  1995-08-16  |  5.2 KB  |  241 lines  |  [TEXT/ttxt]

  1.  
  2. #include "SXextend.h"
  3. #include <memory.h>
  4. #include <string.h>
  5.  
  6. /*
  7.     C support for BitArray class - simplified version
  8.  */
  9.  
  10. #define        SYS_MODULE        NULL
  11. #define        BIT_MODULE        "scratch"
  12.  
  13. typedef enum {
  14.     OPequal,
  15.     OPand,
  16.     OPor,
  17.     OPxor
  18.     }  binaryOpcode ;
  19.     
  20.  
  21. /* prototypes */
  22. void *getPointer(SXobject arg, SXint *objSize);
  23. SXobject binaryOp(SXobject self, SXobject arg2, binaryOpcode op);
  24. SXobject equalOp(SXobject self, SXobject arg2);
  25. SXobject andOp(SXobject self, SXobject arg2);
  26. SXobject orOp(SXobject self, SXobject arg2);
  27. SXobject xorOp(SXobject self, SXobject arg2);
  28. SXobject notOp(SXobject self);
  29. SXobject clearOp(SXobject self);
  30. SXobject setBitOp(SXobject self, SXobject which, SXobject val);
  31. SXobject getBitOp(SXobject self, SXobject which);
  32. SXobject entryPoint(SXobject ld, SXobject grp, SXobject uni);
  33.  
  34.  
  35. /* lock down the external memory object and return it's pointer */
  36. void *getPointer(SXobject arg, SXint *objSize)
  37. {
  38.     *objSize = SXintFrom(SXextGetIV(BIT_MODULE, arg, "bitSize"));
  39.     SXlockMem(arg);
  40.     return SXdereference(arg);
  41. }
  42.  
  43. /* compare two BitArrays */
  44. SXobject binaryOp(SXobject self, SXobject arg2, binaryOpcode op)
  45. {
  46.     register unsigned char    *objp, *otherp;
  47.     SXint                    objSize, otherSize;
  48.     SXint                    opResult;
  49.     SXobject                 arg1, result;
  50.     
  51.     if (op == OPequal) {
  52.         result = trueObject;
  53.         arg1 = self;
  54.         }
  55.     else {
  56.         /* copy of self is destination */
  57.         result = SXextCall(SYS_MODULE, "copy", self, NULL);
  58.         arg1 = result;
  59.         }
  60.     objp = getPointer(arg1, &objSize);
  61.     otherp = getPointer(arg2, &otherSize);
  62.     
  63.     if (objSize != otherSize) {
  64.         SXunlockMem(arg1);
  65.         SXunlockMem(arg2);
  66.         SXextCall(SYS_MODULE, "report", generalError, SXmakeString("BitArray objects must have same size"), NULL);
  67.         return SXundefined;
  68.         }
  69.  
  70.     objSize /= 8;
  71.     while (objSize--) {
  72.         switch (op) {
  73.             case OPequal :    if (*objp != *otherp) {
  74.                                 result = falseObject;
  75.                                 goto bailOut;
  76.                                 }
  77.                             break;
  78.                             
  79.             case OPand    :    *objp &= *otherp;
  80.                             break;
  81.                         
  82.             case OPor    :    *objp |= *otherp;
  83.                             break;
  84.                         
  85.             case OPxor    :    *objp ^= *otherp;
  86.                             break;
  87.             }
  88.             
  89.         objp++;
  90.         otherp++;
  91.         }
  92.  
  93. bailOut:
  94.     SXunlockMem(arg1);
  95.     SXunlockMem(arg2);
  96.     
  97.     return result;
  98. }
  99.  
  100. /* compare two BitArrays */
  101. SXobject equalOp(SXobject self, SXobject arg2)
  102. {
  103.     return binaryOp(self, arg2, OPequal);
  104. }
  105.  
  106. /* and two BitArrays */
  107. SXobject andOp(SXobject self, SXobject arg2)
  108. {
  109.     return binaryOp(self, arg2, OPand);
  110. }
  111.  
  112. /* or two BitArrays */
  113. SXobject orOp(SXobject self, SXobject arg2)
  114. {
  115.     return binaryOp(self, arg2, OPor);
  116. }
  117.  
  118. /* xor two BitArrays */
  119. SXobject xorOp(SXobject self, SXobject arg2)
  120. {
  121.     return binaryOp(self, arg2, OPxor);
  122. }
  123.  
  124. /* logical not of a BitArrays */
  125. SXobject notOp(SXobject self)
  126. {
  127.     unsigned char    *objp;
  128.     SXint            objSize;
  129.     SXobject         result;
  130.     
  131.     /* copy of self is destination */
  132.     result = SXextCall(SYS_MODULE, "copy", self, NULL);
  133.     
  134.     /* get pointer to destination */
  135.     objp = getPointer(result, &objSize);
  136.  
  137.     objSize /= 8;
  138.     while (objSize--) {
  139.         *objp++ = ~ *objp;
  140.         }
  141.     
  142.     SXunlockMem(result);
  143.     return result;
  144. }
  145.  
  146. /* zero out a BitArrays */
  147. SXobject clearOp(SXobject self)
  148. {
  149.     unsigned char    *objp;
  150.     SXint            objSize;
  151.  
  152.     /* get pointer to destination */
  153.     objp = getPointer(self, &objSize);
  154.  
  155.     objSize /= 8;
  156.     while (objSize--) {
  157.         *objp++ = 0;
  158.         }
  159.     
  160.     SXunlockMem(self);
  161.     return self;
  162. }
  163.  
  164.  
  165. /* write nth bit, zero-based, bit 0 is leftmost */
  166. SXobject setBitOp(SXobject self, SXobject which, SXobject val)
  167. {
  168.     unsigned char    *objp;
  169.     SXint            objSize;
  170.     SXint            bit;
  171.     SXint             result;
  172.     
  173.     /* get pointer to self */
  174.     objp = getPointer(self, &objSize);
  175.     bit = SXintFrom(which);
  176.     if (bit < 0 || bit >= objSize) {
  177.         SXunlockMem(self);
  178.         SXextCall(SYS_MODULE, "report", generalError, SXmakeString("BitArray index out of bounds"), NULL);
  179.         return SXundefined;
  180.         }
  181.  
  182.     if (val == SXintToObject(0) || val == falseObject)
  183.         objp[bit / 8] &= ~ (1 << (7 - (bit % 8)));
  184.     else
  185.         objp[bit / 8] |= (1 << (7 - (bit % 8)));
  186.     
  187.     SXunlockMem(self);
  188.     return self;
  189. }
  190.  
  191. /* read nth bit, zero-based, bit 0 is leftmost */
  192. SXobject getBitOp(SXobject self, SXobject which)
  193. {
  194.     unsigned char    *objp;
  195.     SXint            objSize;
  196.     SXint            bit;
  197.     SXint             result;
  198.     
  199.     /* get pointer to self */
  200.     objp = getPointer(self, &objSize);
  201.     bit = SXintFrom(which);
  202.     if (bit < 0 || bit >= objSize) {
  203.         SXunlockMem(self);
  204.         SXextCall(SYS_MODULE, "report", generalError, SXmakeString("BitArray index out of bounds"), NULL);
  205.         return SXundefined;
  206.         }
  207.  
  208.     if (objp[bit / 8] & (1 << (7 - (bit % 8))))
  209.         result = 1;
  210.     else
  211.         result = 0;
  212.     
  213.     SXunlockMem(self);
  214.     return SXintToObject(result);
  215. }
  216.  
  217. /* function executed when this library is loaded */
  218. SXobject entryPoint(SXobject ld, SXobject grp, SXobject uni)
  219. {
  220.     SXobject        myClass;
  221.  
  222.     myClass = SXextGetGlobal(BIT_MODULE, "BitArray");
  223.     if (myClass == SXempty) {
  224.         SXextCall(SYS_MODULE, "report", generalError, SXmakeString("Class BitArray not found"), NULL);
  225.         return falseObject;
  226.         }
  227.     
  228.     /* specialize BitArray with new methods */
  229.     SXextMakeGeneric(BIT_MODULE, "bitEqual", myClass, equalOp);
  230.     SXextMakeGeneric(BIT_MODULE, "bitAnd", myClass, andOp);
  231.     SXextMakeGeneric(BIT_MODULE, "bitOr", myClass, orOp);
  232.     SXextMakeGeneric(BIT_MODULE, "bitXor", myClass, xorOp);
  233.     SXextMakeGeneric(BIT_MODULE, "bitNot", myClass, notOp);
  234.     
  235.     SXextMakeGeneric(BIT_MODULE, "clear", myClass, clearOp);
  236.     SXextMakeGeneric(BIT_MODULE, "getBit", myClass, getBitOp);
  237.     SXextMakeGeneric(BIT_MODULE, "setBit", myClass, setBitOp);
  238.  
  239.     return trueObject;
  240. }
  241.